package hero_info

import (
	"go_server/game_server/api/service/bag"
	"go_server/game_server/api/service/item"
	"go_server/game_server/dataconfig/config_manager"
	"go_server/game_server/event_manager"
	"go_server/game_server/event_manager/event_data/event_impl"
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/game_server/world_manager"
	"go_server/zinx/ziface"
	"go_server/zinx/zlog"
)

func (s *Hero_info_service) S2C_UpLvHero(conn ziface.IConnection, roleid int64, msg *pb.UpLvHeroC2S) pb.ErrorCodeManager {
	hero := Hero_info_serviceObj.LoadByRoleId(roleid)
	if hero != nil {
		msgS2C, code := onUpLvHero(hero, msg.Heroserid, msg.Items)
		defer func() {
			if msgS2C != nil {
				zlog.Debugf("ProtocolManager_UpLvHero %v", msgS2C)
				defer func() {
					conn.SendBuffPBMsg(uint32(pb.ProtocolManager_UpLvHero), msgS2C)
				}()
			}
		}()
		return code
	}
	return pb.ErrorCodeManager_HERO_INFO_NOT_ROLEID
}

func onUpLvHero(hero *Cache_hero_info, heroserid int32, c2sitems map[int32]int32) (*pb.UpLvHeroS2C, pb.ErrorCodeManager) {
	if c2sitems != nil && len(c2sitems) > 0 {
		if uphero, ok := hero.Heros[heroserid]; ok {
			if maxlevel, code, ok := uphero.GetMax_UpLv(hero.RoleId); ok {
				if uphero.LvId < maxlevel {
					if _, ok1 := config_manager.GetStcTableHero_SheetHeroConfig(uphero.CfgId); ok1 {
						if uphero.LvId < maxlevel {
							legitems := util.NewSet[int32]()
							uplevelconsumes := uphero.GetUpgradeLevelConsumes()
							legitems.AddValue(uplevelconsumes.Items.Elements())

							isAllOkItem := true //是否是合法的升级道具
							for id, _ := range c2sitems {
								isAllOkItem = isAllOkItem && legitems.Contains(id)
							}
							if isAllOkItem {
								return onExcHeroUpLv(hero, uphero, c2sitems, maxlevel)
							} else {
								return nil, pb.ErrorCodeManager_HERO_INFO_ERRO_HEROUPLEVELITEM
							}
						} else {
							return nil, pb.ErrorCodeManager_HERO_INFO_NOT_MAXHEROLEVEL
						}
					} else {
						return nil, pb.ErrorCodeManager_HERO_INFO_NOT_HEROCFGID
					}
				} else {
					return nil, pb.ErrorCodeManager_HERO_LIMIT_MAXLEVEL
				}
			} else {
				return nil, code
			}
		} else {
			return nil, pb.ErrorCodeManager_HERO_INFO_NOT_ROLEID
		}
	} else {
		return nil, pb.ErrorCodeManager_HERO_INFO_ERRO_HEROUPLEVELITEM
	}
}

func onExcHeroUpLv(hero *Cache_hero_info, uphero *Cache_hero_info_field_hero, c2sitems map[int32]int32, maxlevel int32) (*pb.UpLvHeroS2C, pb.ErrorCodeManager) {
	curHeroExp := uphero.Exp //英雄当前经验值
	useitems := make(map[int32]int32)
	beforelv := uphero.LvId
	for id, count := range c2sitems {
		if uphero.LvId < maxlevel { //如果英雄等级不是当前最大等级
			if iv, tok := item.GetItemData(id); tok { //获得物品数据
				useitems[id] = 0
				for i := 0; i < int(count); i++ { //循环使用物品
					curHeroExp += iv.HeroExp //物品增加的经验
					isUseOK := false
					needExp := int32(0)
					for {
						if level1, ok1 := config_manager.GetStcTableHero_SheetLevelConfig(uphero.get_next_lv()); ok1 {
							needExp = level1.Consume //升级需要的经验值
							isUseOK = true
							if curHeroExp >= needExp { //如果能升级则升一级，并进入下一等级的经验检测
								curHeroExp -= needExp
								uphero.LvId = uphero.get_next_lv()
								uphero.Exp = curHeroExp
								if uphero.LvId >= maxlevel {
									break
								}
							} else { //经验不够升级，使用下一个道具
								uphero.Exp = curHeroExp
								break
							}
						} else {
							break
						}
					}
					if isUseOK {
						useitems[id]++
					} else {
						break
					}
				}
			}
		}
	}

	isEnough := false
	if len(useitems) > 0 {
		isEnough = bag.CheckBatchItemEnough(hero.RoleId, useitems)
	}
	if isEnough { //物品足够，扣除道具发消息
		uphero.CalculateFight()

		msgS2C := &pb.UpLvHeroS2C{}
		msgS2C.Heros = make([]*pb.HeroCardData, 1)
		msgS2C.Heros[0] = uphero.ToPB_HeroCardData()

		go bag.SubItemBatch(hero.RoleId, useitems)
		go event_manager.EventManagerObj.FireEventData(event_impl.NewUpLevelHeroEvent(world_manager.WorldMgrObj.GetPlayerConn(hero.RoleId), uphero.SerId, beforelv, uphero.LvId))

		defer hero.SaveDB_HeroInfo_Heros()
		return msgS2C, pb.ErrorCodeManager_SUCCESS
	} else {
		return nil, pb.ErrorCodeManager_HERO_INFO_NOTENOUGH_HEROUPLEVELITEM
	}
}
